<template>
  <div class="app" ref="handleParamRef">
    <div class="layout">
      <div class="flex flex-col h-full">
        <!-- 折线图区域 -->
        <div class="flex flex-1 min-h-0">
          <aside
            class="sider pt-3"
            :class="{ 'sider-collapsed': isSiderCollapsed }"
          >
            <!-- <div class="flex w-full gap-[10px]" v-show="!isSiderCollapsed && !showParameterShowBtn">
              <button v-if="mode !== 'online'" class="import-btn tech-btn w-2/4 mb-2" @click="handleImportClick">
                <svg class="h-4 w-4" viewBox="0 0 24 24" fill="none">
                  <path d="M4 16V17C4 18.6569 5.34315 20 7 20H17C18.6569 20 20 18.6569 20 17V16M16 8L12 4M12 4L8 8M12 4V16" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
                </svg>
                文件导入
              </button>
              <button v-if="mode !== 'online'" class="import-btn tech-btn w-2/4 mb-2" @click="handleParameterClick">
                <svg class="h-4 w-4" viewBox="0 0 24 24" fill="none">
                  <path d="M12 6V4M12 6C10.8954 6 10 6.89543 10 8C10 9.10457 10.8954 10 12 10M12 6C13.1046 6 14 6.89543 14 8C14 9.10457 13.1046 10 12 10M12 10V20M6 20H18" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
                </svg>
                文件选择
              </button>
            </div>
            <button v-if="mode !== 'online' && showParameterShowBtn" class="import-btn tech-btn mb-2" @click="handleParameterClickplpm">
              <svg class="h-4 w-4" viewBox="0 0 24 24" fill="none">
                <path d="M12 6V4M12 6C10.8954 6 10 6.89543 10 8C10 9.10457 10.8954 10 12 10M12 6C13.1046 6 14 6.89543 14 8C14 9.10457 13.1046 10 12 10M12 10V20M6 20H18" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
              </svg>
              文件选择
            </button>
            <button class="import-btn tech-btn w-full mb-2" @click="handOpenPluginClick" v-show="!isSiderCollapsed">
              <svg class="h-4 w-4" viewBox="0 0 24 24" fill="none">
                <path d="M20 7h-3a2 2 0 01-2-2V2l4 4zM9 17v-6a2 2 0 012-2h2a2 2 0 012 2v6a2 2 0 01-2 2h-2a2 2 0 01-2-2z" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
                <path d="M9 5H7a2 2 0 00-2 2v6a2 2 0 002 2h2a2 2 0 002-2V7a2 2 0 00-2-2z" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
              </svg>
              <span v-if="mode !== 'online'">数据插件管理</span>
              <span v-if="mode === 'online'">插件管理</span>
            </button> -->
            <parameter-selector
              ref="parameterSelector"
              v-show="!isSiderCollapsed"
              v-model:selectedParameters="selectedParameters"
              v-model:selectedTasks="selectedTasks"
              :parameters="parameters"
              :tasks="tasks"
              :isLoading="isLoading"
              :unitCodeList="unitCodeList"
              class="h-full overflow-hidden"
              @save:task="handleSaveTask"
              @save:save="handleSaveParameter"
              @save:delete="handleDeleteTask"
              @update:viewSettings="handleViewSettingsUpdate"
              @handleChangeTask="handleChangeTask"
              @handleParameterError="handleParameterError"
              @refresh:parameter="handleRefreshParameter"
              @refresh:dataViewer="handleRefreshDataViewer"
            />
            <!-- <button class="sider-toggle" @click="toggleSider">
              <svg class="h-4 w-4" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
                <path v-if="isSiderCollapsed" d="M13 5l7 7-7 7M5 5l7 7-7 7"></path>
                <path v-else d="M11 5l-7 7 7 7M19 5l-7 7 7 7"></path>
              </svg>
            </button> -->
          </aside>
          <main class="content">
            <div class="content-layout">
              <div class="main-content">
                <data-viewer
                  :selectedParameters="selectedParameters"
                  :selectedVirtualParamsName="selectedVirtualParamsName"
                  :selectedVirtualParamsInfo="selectedVirtualParams"
                  :viewSettings="viewSettings"
                  :selectedParametersInfo="selectedParametersInfo"
                  :selectedChannel="selectedChannel"
                  :isSiderCollapsed="isSiderCollapsed"
                  :changeTask="changeTask"
                  @update:cursorPosition="handleCursorPositionUpdate"
                  @update:cursorData="handleCursorDataUpdate"
                  @update:measurementData="handleMeasurementDataUpdate"
                  @update:measurementLoading="handleMeasurementLoadingUpdate"
                  @update:viewSettings="handleViewSettingsUpdate"
                  @update:selectedParametersList="
                    handleSelectedParametersListUpdate
                  "
                  @update:loading="handleLoadingUpdate"
                  @handleDataError="handleParameterError"
                  @open-virtual-param="showVirtualParamDialog"
                  @clear-selected-virtual-parameter="
                    clearSelectedVirtualParameter
                  "
                  @toggle-fault-mode="handleToggleFaultMode"
                  @open-export-data="handleOpenExportData"
                  @open-similarity-search="handleOpenSimilaritySearch"
                  @parametersRemoved="handleParametersRemoved"
                  @update:isMeasuring="handleIsMeasuringUpdate"
                  ref="dataViewerRef"
                />
              </div>
              <div class="side-content">
                <parameter-value-display
                  ref="parameterValueDisplayRef"
                  :cursorPosition="cursorPosition"
                  :cursorData="cursorData"
                  :selectedParameters="selectedParameters"
                  :measurementData="measurementData"
                  :isMeasurementLoading="isMeasurementLoading"
                  :viewSettings="viewSettings"
                  :selectedParametersInfo="selectedParametersInfo"
                  :selectedParametersList="selectedParametersList"
                  :isFaultModeActive="isFaultModeActive"
                  :faultList="faultList"
                  @showParameterYAxis="handleShowParameterYAxis"
                  @highlightLine="handleHighlightLine"
                  @highlightAllChannels="handleHighlightAllChannels"
                  @removeParameter="handleRemoveParameter"
                  @toggle-fault-mode="handleToggleFaultMode"
                  @fault-selected="handleFaultSelected"
                  @fault-display-mode-changed="handleFaultDisplayModeChanged"
                />
              </div>
            </div>
          </main>
        </div>
      </div>
    </div>
  </div>
  <!-- 文件导入模态窗口 -->
  <div v-if="showPluginModal">
    <file-import
      v-model:visible="showPluginModal"
      @confirm="handleFileImportConfirm"
      @cancel="handlePluginModalClose"
      @success="handleFileImportSuccess"
    />
  </div>
  <!-- 编辑回访任务 -->
  <div v-if="showTaskModel">
    <TaskModel
      v-model:visible="showTaskModel"
      :selectedParame="selected"
      :paramName="taskName"
      :parameters="parameters"
      :viewSettings="viewSettings"
      @success="PublicHandFuncontionEnit"
    />
  </div>
  <!-- 保存测点测点组件 -->
  <div v-if="showSaveModel">
    <SaveParameterModel
      ref="saveParameterModelRef"
      v-model:visible="showSaveModel"
      :selecteSaveParame="selectedSave"
      :viewSettings="viewSettings"
      @success="PublicHandFuncontion"
    />
  </div>
  <!-- 删除 -->
  <div v-if="showDeleteModel">
    <ConfirmDeletionModel
      v-model:visible="showDeleteModel"
      :selectedParame="selectDelete"
      @success="PublicHandFuncontionEnit"
    />
  </div>
  <div v-if="showPluginModel">
    <PluginModel v-model:visible="showPluginModel" @confirm="handleConfirm" />
  </div>

  <div v-if="showParameterShowModel">
    <ParameterModel
      ref="parameterModelRef"
      v-model:visible="showParameterShowModel"
      @confirm="getRoute"
    />
  </div>
  <!-- 消息提示组件 -->
  <Message ref="messageRef" />

  <!-- 虚拟参数弹窗 -->
  <VirtualParameterDialog
    ref="virtualParameterDialogRef"
    v-if="showVirtualParamModal"
    :parameters="parameters"
    :selectedVirtualParams="selectedVirtualParams"
    @close="showVirtualParamModal = false"
    @draw-virtual-param="addVirtualToSelectedParams"
  />
  <!-- 数据导出模态框 -->
  <ExportFileModal
    v-if="showExportModal"
    ref="exportFileModalRef"
    :visible="showExportModal"
    :parameters="parameters"
    @close="showExportModal = false"
  />
  <!-- 相似性检索模态框 -->
  <SimilaritySearchModal
    v-if="showSimilaritySearchModal"
    ref="similaritySearchModalRef"
    :visible="showSimilaritySearchModal"
    :selectedChannel="selectedChannel"
    :selectedParametersInfo="selectedParametersInfo"
    @close="showSimilaritySearchModal = false"
    @openAddSample="openAddSample"
    @editSample="handleEditSample"
    @playSample="handlePlaySample"
    @annotateResult="handleAnnotate"
    @clearAnnotateResult="handleClearAnnotate"
    @batchAnnotate="handleBatchAnnotate"
    @batchClearAnnotate="handleBatchClearAnnotate"
    @clearAllAnnotate="handleClearAllAnnotate"
  />

  <!-- 新增样本弹窗 -->
  <AddSampleDialog
    v-if="showAddSampleDialog"
    ref="addSampleDialogRef"
    :visible="showAddSampleDialog"
    :parameters="parameters"
    :selectedParametersInfo="selectedParametersInfo"
    :measurementData="measurementData"
    :selectedChannel="selectedChannel"
    :editSample="editSampleData"
    @close="closeAddSampleDialog"
    @save="handleSaveSample"
    @updateCursors="handleUpdateCursors"
  />

  <!-- 引导蒙层 -->
  <div
    v-if="showGuide && mode === 'offline'"
    class="guide-overlay"
    @click="closeGuide"
  >
    <div class="guide-modal modal-main" @click.stop>
      <div class="guide-header modal-header">
        <h3 class="guide-title">欢迎使用数据回放系统</h3>
        <button class="guide-close" @click="closeGuide">
          <svg
            class="h-4 w-4"
            viewBox="0 0 24 24"
            fill="none"
            stroke="currentColor"
            stroke-width="2"
          >
            <path d="M18 6L6 18M6 6l12 12" />
          </svg>
        </button>
      </div>
      <div class="guide-content">
        <p>请先导入文件以开始使用系统功能</p>
        <button class="import-btn tech-btn" @click="startGuide">确定</button>
      </div>
    </div>
  </div>
  <!-- 全局loading遮罩层 -->
  <div v-if="loading" class="loading-overlay">
    <div class="spinner"></div>
    <div class="loading-text">{{ loadingText }}</div>
  </div>
</template>

<script setup lang="ts">
import ParameterSelector from "./main/ParameterSelector.vue";
import DataViewer from "./main/DataViewer.vue";
import ParameterValueDisplay from "./main/ParameterValueDisplay.vue";
import SaveParameterModel from "./playbackTask/saveParameterModel.vue";
import ParameterModel from "@/views/parameter/parameterModel.vue";
import { ref, watch, onMounted, nextTick } from "vue";
import { useRoute } from "vue-router";
import type { Parameter, Task, ParameterViewSetting } from "../types";
import WithAPI from "./parameter/parameter.api.ts";
import EquipmentAPI from "./parameter/equipment.api.ts";
// 导入插件选择和文件导入组件
import FileImport from "./fileImport/index.vue";
import { useRouter } from "vue-router";
import TaskModel from "@/views/playbackTask/taskModel.vue";
import ConfirmDeletionModel from "@/views/playbackTask/ConfirmDeletionModel.vue";
import Message from "@/components/BaseComponents/Message.vue";
import PluginModel from "@/views/plugin/pluginModel.vue";
import VirtualParameterDialog from "./VirtualParameter/VirtualParameterDialog.vue";
import ExportFileModal from "@/views/exportData/exportDataModal.vue";
import SimilaritySearchModal from "@/views/similaritySearch/SimilaritySearchDialog.vue";
import AddSampleDialog from "@/views/similaritySearch/AddSampleDialog.vue";
import request from "@/utils/request";
import { useSessionStore } from "@/stores/session";
import { useSimilarityStore } from "@/stores/similarity";

// 监听url
const unitCode = ref();
const protocolId = ref();
const flag = ref();
const mode = localStorage.getItem("mode");
const importFileIndex = ref();
const rjNo = ref();
const sessionId = ref();
const userId = ref();
const filesData = ref<any[]>([]);
const unitCodeList = ref<string[]>([]);
// 存储从URL解析出的drawCurve参数名称列表
const drawCurveParams = ref<string[]>([]);

// 消息提示组件引用
const messageRef = ref<InstanceType<typeof Message> | null>(null);
const router = useRouter();
// 添加视图设置状态
const viewSettings = ref<Record<string, ParameterViewSetting>>({});

// 创建对DataViewer的引用
const dataViewerRef = ref<InstanceType<typeof DataViewer> | null>(null);

// 创建对parameterValueDisplay的引用
const parameterValueDisplayRef = ref(null);

// 创建对saveParameterModel的引用
const saveParameterModelRef = ref<InstanceType<
  typeof SaveParameterModel
> | null>(null);

// 创建对VirtualParameterDialog的引用
const virtualParameterDialogRef = ref<InstanceType<
  typeof VirtualParameterDialog
> | null>(null);

// 创建对exportFileModal的引用
const exportFileModalRef = ref<InstanceType<typeof ExportFileModal> | null>(
  null
);

// 创建对similaritySearchModal的引用
const similaritySearchModalRef = ref<InstanceType<
  typeof SimilaritySearchModal
> | null>(null);

// 创建对addSampleDialogRef的引用
const addSampleDialogRef = ref<InstanceType<typeof AddSampleDialog> | null>(
  null
);

// 添加参数数据状态
const parametersData = ref<
  Record<string, Record<string, { timestamp: number; value: number }[]>>
>({});
const parameterSelector = ref();
// 控制弹窗显示状态
const showPluginModal = ref(false);
const showTaskModel = ref(false);
const showDeleteModel = ref(false);
const showPluginModel = ref(false);
const showParameterShowModel = ref(false);
const showSaveModel = ref(false);
const showFileImportModal = ref(false);
const showVirtualParamModal = ref(false);
const selectedPlugin = ref<any>();
const showExportModal = ref(false);
const showSimilaritySearchModal = ref(false);
const showAddSampleDialog = ref(false);
const editSampleData = ref(null); // 添加编辑样本数据
const parameterModelRef = ref<InstanceType<typeof ParameterModel> | null>(null);
// 添加引导相关状态
const showGuide = ref(false);

// 添加loading状态
const isLoading = ref(false);
// 全屏loading
const loading = ref(false);
const loadingText = ref("");

// 模式相关状态（在flag和protocolId定义之后）
const isFaultModeActive = ref(false);
const faultIds = ref<string[]>([]);
// 模拟故障数据
const faultList = ref([]);

// 处理loading状态更新
const handleLoadingUpdate = (loading: boolean) => {
  isLoading.value = loading;
};

// 文件导入按钮点击事件
const handleImportClick = () => {
  showPluginModal.value = true;
};
// 处理插件模态窗口的关闭
const handlePluginModalClose = () => {
  showPluginModal.value = false;
};
// 处理插件选择确认
const handlePluginSelected = (plugin: any) => {
  // 设置选中的插件并打开文件导入弹窗，不关闭插件选择弹窗
  selectedPlugin.value = plugin;
  showFileImportModal.value = true;
};

// 回放任务的名称
const taskName = ref("");
// 格式化文件大小辅助函数
const formatFileSize = (bytes: number) => {
  if (bytes === 0) return "0 Bytes";

  const k = 1024;
  const sizes = ["Bytes", "KB", "MB", "GB"];
  const i = Math.floor(Math.log(bytes) / Math.log(k));

  return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + " " + sizes[i];
};

const parameters = ref<Parameter[]>([]);

const tasks = ref<Task[]>([]);

const selectedParameters = ref<string[]>([]);
const selected = ref<{ id: any; name: any; type: any }[]>([]);
const selectedSave = ref<{ id: any; name: any; type: any }[]>([]);
const selectDelete = ref<string>();
const selectedParametersList = ref<string[]>([]); //Rectime 在第一个
const selectedParametersInfo = ref<
  { id: string; name: string; type: string }[]
>([]);
const selectedTasks = ref<string[]>([]);
const cursorPosition = ref<number>(0);
//跳转到当前页面传参时,不展示文件选择、文件导入
const showParameterShowBtn = ref(false);

const measurementData = ref<
  | {
      cursor1: number;
      cursor2: number;
      deltaTime: number;
      measurementResults: Record<
        string,
        {
          parameterId: string;
          channelId: string;
          min: number;
          max: number;
          avg: number;
          fluctuation: number;
        }
      >;
    }
  | undefined
>(undefined);

// 添加游标数据状态类型定义
interface CursorDataPoint {
  value: number;
  timestamp: number;
  color: string;
}
const cursorData = ref<Record<string, Record<string, CursorDataPoint>>>({});

// 监听参数选择变化
watch(
  selectedParameters,
  (newParams) => {
    selectedParametersInfo.value = [];
    // 为新选择的参数创建默认视图设置

    // 新增已选参数的信息集合
    newParams.forEach((paramName) => {
      // 查找参数信息，包括查找在children中的子参数
      let paramInfo = parameters.value.find((p) => p.name === paramName);
      if (paramInfo) {
        const paramExists = selectedParametersInfo.value.some(
          (item) => item.name === paramInfo.name
        );
        if (!paramExists) {
          selectedParametersInfo.value.push(paramInfo);
        }
      } else {
        // 如果在顶层参数中找不到，尝试在子参数中查找
        // 遍历所有有children的参数
        for (const p of parameters.value) {
          if (p.children && p.children.length > 0) {
            const childParam = p.children.find(
              (child) => child.name === paramName
            );
            if (childParam) {
              paramInfo = childParam;
              selectedParametersInfo.value.push(paramInfo);
              //燃机查开关量需带上父级
              if (flag.value === "RJ") {
                // 检查父级参数是否已经存在，避免重复添加
                const parentExists = selectedParametersInfo.value.some(
                  (item) => item.name === p.name
                );
                if (!parentExists) {
                  selectedParametersInfo.value.push(p);
                }
              }
              break;
            }
          }
        }
      }

      // 设置默认显示方式与参数类型一致
      const defaultDisplayMode = paramInfo?.displayType;

      // 为每个通道创建设置
      const channelIds = ["leftA", "leftB", "rightA", "rightB", "RJ"];
      channelIds.forEach((channelId) => {
        const settingKey = `${paramName}:${channelId}`;

        if (!viewSettings.value[settingKey]) {
          viewSettings.value[settingKey] = {
            parameterId: paramName,
            channelId: channelId,
            displayMode: defaultDisplayMode,
            lineWidth: 1.5,
            visible: true,
          };
        }
      });
    });

    // 移除未选择的参数设置
    Object.keys(viewSettings.value).forEach((key) => {
      const paramId = key.split(":")[0];
      if (!newParams.includes(paramId)) {
        delete viewSettings.value[key];
      }
    });
  },
  { deep: true }
);

// 更新游标位置回调
const handleCursorPositionUpdate = (value: number) => {
  cursorPosition.value = value;
};
// 更新游标数据回调
const handleCursorDataUpdate = (
  value: Record<string, Record<string, CursorDataPoint>>
) => {
  console.log("App.vue - handleCursorDataUpdate received data");
  cursorData.value = value;
};

// 更新测量数据回调
const handleMeasurementDataUpdate = (
  value:
    | {
        cursor1: number;
        cursor2: number;
        measurementResults: Record<
          string,
          {
            parameterId: string;
            channelId: string;
            min: number;
            max: number;
            avg: number;
            fluctuation: number;
          }
        >;
      }
    | undefined
) => {
  measurementData.value = value;
};

// 处理测量数据loading状态更新
const isMeasurementLoading = ref(false);
const handleMeasurementLoadingUpdate = (value: boolean) => {
  isMeasurementLoading.value = value;
};
const handleParameterClick = () => {
  showParameterShowModel.value = true;
  // router.push('/parameter');
};
const handleParameterClickplpm = async () => {
  showParameterShowModel.value = true;
  await new Promise((resolve) => setTimeout(resolve, 100));
  parameterModelRef.value?.autoSelectFile(filesData.value, false);
};
function handOpenPluginClick() {
  showPluginModel.value = true;
}
// 添加视图设置更新回调
const handleViewSettingsUpdate = (
  value: Record<string, ParameterViewSetting>
) => {
  viewSettings.value = value;
};

// 添加参数列表更新回调
const handleSelectedParametersListUpdate = (value: string[]) => {
  selectedParametersList.value = value;
};

// 处理显示参数Y轴事件
const handleShowParameterYAxis = (paramId: string) => {
  if (dataViewerRef.value) {
    dataViewerRef.value.showParameterYAxis(paramId);
  }
};
// 添加参数数据更新回调
const handleParametersDataUpdate = (
  value: Record<string, Record<string, { timestamp: number; value: number }[]>>
) => {
  console.log("App.vue - handleParametersDataUpdate:", value);
  parametersData.value = value;
};

// 监听插件选择模态窗口状态
watch(
  showPluginModal,
  (newVal) => {
    console.log("Index: showPluginModal changed to", newVal);
  },
  { immediate: true }
);

// 处理文件导入模态窗口的打开
const openFileImportModal = () => {
  showFileImportModal.value = true;
};

// 处理文件导入模态窗口的关闭
const handleFileImportModalClose = () => {
  showFileImportModal.value = false;
};

// 处理文件导入确认
const handleFileImportConfirm = (data: any) => {
  console.log("App.vue - handleFileImportConfirm:", data);
  showFileImportModal.value = false;
};
// 处理文件导入成功后提示选择文件
const handleFileImportSuccess = () => {
  // 设置已导入文件的标记
  localStorage.setItem("hasImportedFile", "true");

  messageRef.value?.show({
    type: "success",
    content: "文件导入成功，请点击文件选择按钮选择要回放的文件",
    duration: 5000,
  });
};

// 处理修改任务事件
const handleSaveTask = (taskData: {
  parameters: any[];
  showTask: boolean;
  taskName: string;
}) => {
  showTaskModel.value = taskData.showTask;
  taskName.value = taskData.taskName;
};
// 处理保存参数事件
const handleSaveParameter = (taskData: {
  parameters: any[];
  showTask: boolean;
  taskName: string;
}) => {
  showSaveModel.value = taskData.showTask;
  selectedSave.value = taskData.parameters;
  nextTick(() => {
    saveParameterModelRef.value?.showTaskName(taskData.taskName);
  });
};
// 处理修改任务事件
const handleDeleteTask = (taskData: { taskId: string; showTask: boolean }) => {
  showDeleteModel.value = taskData.showTask;
  selectDelete.value = taskData.taskId;
};

// 处理修改任务事件
const changeTask = ref(false);
const handleChangeTask = () => {
  changeTask.value = true;
};

const route = useRoute();
const selectedChannel = ref<any[]>([]);
async function getRoute(draw) {
  parameters.value = [];
  const drawParam = draw;
  if (drawParam && typeof drawParam === "string") {
    try {
      selectedChannel.value = JSON.parse(drawParam);
      console.log("Received draw data:", selectedChannel.value);
      let filesName: any[] = [];
      selectedChannel.value.forEach((item: any) => {
        if (item.fileName) {
          filesName.push(item.fileName);
        }
      });
      let params = { files: filesName.join(",") };
      // 获取参数
      WithAPI.getDataReplay(params)
        .then((res: any) => {
          if (res && res.code === 200) {
            if (res.data.length == 0) {
              messageRef.value?.show({
                type: "warning",
                content: "没有找到参数",
                duration: 3000,
              });
            }
            parameters.value = res.data;
            parameters.value.forEach((item: Parameter) => {
              // 设置参数类型
              item.displayType = item.mode === 0 ? "continuous" : "discrete";
              if (item.children) {
                item.children.forEach((child: Parameter) => {
                  child.displayType =
                    child.mode === 0 ? "continuous" : "discrete";
                });
              }
            });
            // 重置绘图区域
            dataViewerRef.value?.resetSvg();
            // 清空已选参数和任务
            parameterSelector.value?.clearSelectedTask();
            //清空选择故障
            parameterValueDisplayRef.value?.clearSelectedFault();
          }
        })
        .catch((error: any) => {
          messageRef.value?.show({
            type: "error",
            content: error.response.data.msg || "参数获取失败",
            duration: 3000,
          });
        });
      // 查询故障
      if (mode === "plpm" && importFileIndex.value) {
        try {
          let params: { importFileIndex: any; channelId: any }[] = [];
          selectedChannel.value.forEach((item: any) => {
            if (item.fileName) {
              // 在fileData中匹配对应fileName的importFileIndex
              const itemImportFileIndex = filesData.value.find(
                (file: any) => file.fileName === item.fileName
              )?.importFileIndex;
              params.push({
                importFileIndex: itemImportFileIndex,
                channelId: item.channelId,
              });
            }
          });
          const res = await request<any>({
            url: "/dataResultFault/queryFaultList",
            method: "POST",
            data: params,
          });
          if (res && res.code === 200) {
            faultList.value = res.data;
          }
        } catch (error: any) {
          messageRef.value?.show({
            type: "error",
            content: error.response.data.msg || "故障查询失败",
            duration: 3000,
          });
        }
      }
    } catch (error) {
      console.error("Failed to parse draw parameter:", error);
    }
  }
  showParameterShowModel.value = false;
}

//燃机插件回调
const handleConfirm = (data: any) => {
  // 获取参数
  messageRef.value?.show({
    type: "success",
    content: data,
    duration: 3000,
  });
};

// 添加侧边栏收缩状态
const isSiderCollapsed = ref(false);

// 侧边栏收缩/展开切换函数
const toggleSider = () => {
  isSiderCollapsed.value = !isSiderCollapsed.value;
};

// 关闭引导
const closeGuide = () => {
  showGuide.value = false;
  localStorage.setItem("guideShown", "true");
};

// 启动导入流程
const startGuide = () => {
  closeGuide();
};

// 解析drawCurve参数并存储
const parseDrawCurveParams = (
  drawCurveValue: string | string[] | undefined
) => {
  debugger;
  if (!drawCurveValue) {
    drawCurveParams.value = [];
    return;
  }

  // 如果是数组，取第一个元素
  const drawCurveStr = Array.isArray(drawCurveValue)
    ? drawCurveValue[0]
    : drawCurveValue;

  if (typeof drawCurveStr !== "string" || !drawCurveStr.trim()) {
    drawCurveParams.value = [];
    return;
  }

  // URL解码，将%2C转换为逗号
  const decoded = decodeURIComponent(drawCurveStr);
  // 按逗号分割参数名称
  const params = decoded
    .split(",")
    .map((p) => p.trim())
    .filter((p) => p.length > 0);
  drawCurveParams.value = params;
  console.log("解析drawCurve参数:", drawCurveParams.value);
};

// 根据drawCurve参数匹配并设置选中状态
// 仅在页面跳转（如路由变更）或者刷新整个浏览器页面时触发
// 也就是：
// 1. 监听 route.query 变化（如页面跳转），在机组参数加载完成后调用
// 2. 浏览器刷新会重新加载参数时，也会触发
const matchAndSelectParams = () => {
  debugger;
  console.log("[matchAndSelectParams] 调用, 参数如下：", {
    drawCurve参数: drawCurveParams.value,
    参数列表长度: parameters.value.length,
  });

  if (drawCurveParams.value.length === 0 || parameters.value.length === 0) {
    console.log(
      "[matchAndSelectParams] 没有需要匹配的drawCurve参数或参数列表为空：",
      {
        drawCurve参数: drawCurveParams.value,
        参数列表长度: parameters.value.length,
      }
    );
    return;
  }

  // 收集所有匹配的参数名称（仅匹配主参数，不考虑子参数）
  const matchedParamNames: string[] = [];

  // 遍历参数列表，查找匹配的参数（仅匹配主参数，不考虑子参数）
  parameters.value.forEach((param: Parameter) => {
    // 检查主参数是否匹配
    if (drawCurveParams.value.includes(param.name)) {
      console.log("[matchAndSelectParams] 匹配到主参数：", param.name);
      matchedParamNames.push(param.name);
    }
  });

  // 如果有匹配的参数，设置选中状态
  if (matchedParamNames.length > 0) {
    // 使用nextTick确保参数列表已渲染
    nextTick(() => {
      if (parameterSelector.value) {
        // 直接设置selectedParams数组
        parameterSelector.value.selectedParams = [...matchedParamNames];
        console.log(
          "[matchAndSelectParams] 自动选中匹配的参数：",
          matchedParamNames
        );
      } else {
        console.warn("[matchAndSelectParams] parameterSelector 未设置。");
      }
    });
  } else {
    console.log(
      "[matchAndSelectParams] 未找到匹配的参数：",
      drawCurveParams.value
    );
  }
};

// 查询设备列表的函数
const fetchEquipmentList = async () => {
  try {
    const res = await EquipmentAPI.getEquipmentList();
    if (res && res.code === 200) {
      // 优先使用 result 字段，如果没有则使用 data 字段（兼容性处理）
      unitCodeList.value = res.result || res.data || [];
      console.log("查询设备列表成功，数量:", unitCodeList.value.length);
    } else {
      console.warn("查询设备列表返回异常，code:", res?.code);
      unitCodeList.value = [];
    }
  } catch (error: any) {
    console.error("Failed to fetch equipment list:", error);
    unitCodeList.value = [];
    messageRef.value?.show({
      type: "error",
      content: error.response?.data?.msg || error.message || "设备列表获取失败",
      duration: 3000,
    });
  }
};

onMounted(() => {
  // 获取并处理路由参数
  // getRoute(draw);
  // 自动打开文件导入模态窗口，引导用户首先进行文件导入
  // 可以添加延时以确保页面完全加载
  setTimeout(() => {
    // 检查是否是首次访问
    const hasImportedFile = localStorage.getItem("hasImportedFile");
    const guideShown = localStorage.getItem("guideShown");

    if (!hasImportedFile && !guideShown) {
      showGuide.value = true;
    }
  }, 500);
});

/**
 *  公共处理弹窗方法
 * @param type 弹窗类型
 * @param content 提示语句
 * @param duration 展示时长
 * @constructor
 */
function PublicHandFuncontion(messge: {
  type: string;
  content: string;
  duration: number;
}) {
  messageRef.value?.show({
    type: messge.type,
    content: messge.content,
    duration: messge.duration,
  });
  parameterSelector.value.getAllTask();
  // parameterSelector.value.clearSelectedTask();
}
function PublicHandFuncontionEnit(messge: {
  type: string;
  content: string;
  duration: number;
}) {
  messageRef.value?.show({
    type: messge.type,
    content: messge.content,
    duration: messge.duration,
  });
  parameterSelector.value.getAllTask();
  parameterSelector.value.clearSelectedTask();
}

// const drawParam = ref('');
// function handleParameterConfirm(draw) {
//   drawParam.value = draw;
//   // 你可以在这里做后续处理，比如解析、请求等
// }

// 处理来自ParameterValueDisplay的highlightLine事件
const handleHighlightLine = (paramId: string, channelId: string) => {
  // 调用DataViewer组件的handleHighlightLine方法
  if (dataViewerRef.value) {
    dataViewerRef.value.handleHighlightLine(paramId, channelId);
  }
};

// 处理来自ParameterValueDisplay的highlightAllChannels事件
const handleHighlightAllChannels = (paramId: string) => {
  // 调用DataViewer组件的handleHighlightAllChannels方法
  if (dataViewerRef.value) {
    dataViewerRef.value.handleHighlightAllChannels(paramId);
  }
};

// 处理来自ParameterValueDisplay的removeParameter事件
const handleRemoveParameter = (paramId: string) => {
  // 从选中参数列表中移除指定参数
  selectedParameters.value = selectedParameters.value.filter(
    (id) => id !== paramId
  );
  selectedParametersList.value = selectedParametersList.value.filter(
    (id) => id !== paramId
  );
  selectedParametersInfo.value = selectedParametersInfo.value.filter(
    (param) => param.name !== paramId
  );

  // 同步更新ParameterSelector组件的选中状态
  if (parameterSelector.value) {
    parameterSelector.value.removeSelectedParam(paramId);
  }

  // 更新视图设置，移除该参数的设置
  if (viewSettings.value[paramId]) {
    delete viewSettings.value[paramId];
  }

  console.log("参数已移除:", paramId);
};

const handleParameterError = (type: string, content: string) => {
  messageRef.value?.show({
    type: type,
    content: content,
    duration: 2000,
  });
};

const selectedVirtualParams = ref([]);
const selectedVirtualParamsName = ref([]);

// 显示虚拟参数弹窗
const showVirtualParamDialog = () => {
  showVirtualParamModal.value = true;
};

// 清除虚拟参数
const clearSelectedVirtualParameter = () => {
  selectedVirtualParams.value = [];
  selectedVirtualParamsName.value = [];
  virtualParameterDialogRef.value?.clearSelectedParams();
};

// 绘制虚拟参数回调，将虚拟参数添加到已选参数列表
const addVirtualToSelectedParams = (virtualParams: any) => {
  selectedVirtualParams.value = virtualParams;
  selectedVirtualParamsName.value = virtualParams.map((p) => p.name);
  // 合并普通参数和虚拟参数
  selectedParametersInfo.value = [
    ...selectedParametersInfo.value,
    ...selectedVirtualParams.value,
  ];

  selectedParameters.value = [
    ...selectedParameters.value,
    ...selectedVirtualParamsName.value,
  ];
  console.log("虚拟参数已添加到已选列表:", virtualParams);
};

// 监听路由
watch(
  route.query,
  async (newVal) => {
    // 初始化loading状态（如果之前有loading状态，先清除）
    isLoading.value = false;

    // 解析drawCurve参数
    console.log(
      "[watch route.query] 开始解析drawCurve参数，route.query.drawCurve:",
      route.query.drawCurve
    );
    parseDrawCurveParams(route.query.drawCurve);
    console.log(
      "[watch route.query] 解析完成，drawCurveParams.value:",
      drawCurveParams.value
    );

    // 查询设备列表（机组编号列表）
    await fetchEquipmentList();
    if (route.query.startTime) {
      if (parameterSelector.value) {
        parameterSelector.value.startDateTime = route.query.startTime;
        localStorage.setItem("startTime", route.query.startTime);
      }
    } else {
      localStorage.setItem("startTime", "");
    }
    if (route.query.endTime) {
      if (parameterSelector.value) {
        parameterSelector.value.endDateTime = route.query.endTime;
        localStorage.setItem("endTime", route.query.endTime);
      }
    } else {
      localStorage.setItem("endTime", "");
    }
    if (route.query.unitCode) {
      unitCode.value = route.query.unitCode;
      if (parameterSelector.value) {
        parameterSelector.value.selectedUnit = unitCode.value;
      }
      localStorage.setItem("unitCode", unitCode.value);

      // 根据设备编号查询参数
      const queryParamsOnline = async () => {
        try {
          isLoading.value = true;
          const res = await EquipmentAPI.getParametersByEquipment(
            unitCode.value
          );

          if (res && res.code === 200) {
            // 优先使用 result 字段，如果没有则使用 data 字段（兼容性处理）
            const paramsList = res.result || res.data || [];

            // 将后端返回的 ParameterDTO 转换为前端需要的 Parameter 格式
            parameters.value = paramsList.map((param: any) => {
              const parameter: Parameter = {
                id: param.ckField || param.paramName || "",
                name: param.paramName || "",
                type: param.type,
                mode: param.type,
                displayType: param.type === 0 ? "continuous" : "discrete",
                // 如果有子参数，也需要转换
                children: param.children
                  ? param.children.map((child: any) => ({
                      id: child.ckField || child.paramName || "",
                      name: child.paramName || "",
                      type: child.type,
                      mode: child.type,
                      displayType: child.type === 0 ? "continuous" : "discrete",
                    }))
                  : undefined,
              };
              return parameter;
            });

            // 重置绘图区域
            dataViewerRef.value?.resetSvg();
            // 清空已选参数和任务
            parameterSelector.value?.clearSelectedTask();
            isLoading.value = false;

            console.log("查询参数成功，参数数量:", parameters.value.length);

            // 参数列表加载完成后，如果URL中有drawCurve参数，进行匹配并设置选中状态
            if (drawCurveParams.value.length > 0) {
              matchAndSelectParams();
            }
          } else {
            console.warn("查询参数返回异常，code:", res?.code);
            parameters.value = [];
            isLoading.value = false;
            messageRef.value?.show({
              type: "warning",
              content: res?.message || "参数获取失败",
              duration: 3000,
            });
          }
        } catch (error: any) {
          console.error("Failed to fetch parameters:", error);
          parameters.value = [];
          isLoading.value = false;
          messageRef.value?.show({
            type: "error",
            content:
              error.response?.data?.msg || error.message || "参数获取失败",
            duration: 3000,
          });
        }
      };

      // 直接调用查询参数（确保在watch(route.query)中能触发参数查询）
      queryParamsOnline();
    } else {
      // URL中没有unitCode，清空相关数据
      localStorage.setItem("unitCode", "");
      parameters.value = [];
      // 确保loading状态被清除
      isLoading.value = false;
    }
  },
  { immediate: true, deep: true }
);

const handleRefreshParameter = async () => {
  // 从parameterSelector获取当前选中的机组编号
  const currentUnitCode =
    parameterSelector.value?.selectedUnit || localStorage.getItem("unitCode");

  if (!currentUnitCode) {
    console.warn("未选择机组编号，无法查询参数");
    messageRef.value?.show({
      type: "warning",
      content: "请先选择机组编号",
      duration: 3000,
    });
    return;
  }

  unitCode.value = currentUnitCode;

  try {
    isLoading.value = true;
    const res = await EquipmentAPI.getParametersByEquipment(currentUnitCode);

    if (res && res.code === 200) {
      // 优先使用 result 字段，如果没有则使用 data 字段（兼容性处理）
      const paramsList = res.result || res.data || [];

      // 将后端返回的 ParameterDTO 转换为前端需要的 Parameter 格式
      parameters.value = paramsList.map((param: any) => {
        const parameter: Parameter = {
          id: param.ckField || param.paramName || "",
          name: param.paramName || "",
          type: param.type,
          mode: param.type,
          displayType: param.type === 0 ? "continuous" : "discrete",
          // 如果有子参数，也需要转换
          children: param.children
            ? param.children.map((child: any) => ({
                id: child.ckField || child.paramName || "",
                name: child.paramName || "",
                type: child.type,
                mode: child.type,
                displayType: child.type === 0 ? "continuous" : "discrete",
              }))
            : undefined,
        };
        return parameter;
      });

      // 重置绘图区域
      dataViewerRef.value?.resetSvg();
      // 清空已选参数和任务
      parameterSelector.value?.clearSelectedTask();
      isLoading.value = false;

      console.log("查询参数成功，参数数量:", parameters.value.length);

      // 参数列表加载完成后，如果URL中有drawCurve参数，进行匹配并设置选中状态
      // 注意：这里只在watch(route.query)中的queryParamsOnline函数中调用，符合注释说明
      if (drawCurveParams.value.length > 0) {
        matchAndSelectParams();
      }
    } else {
      console.warn("查询参数返回异常，code:", res?.code);
      parameters.value = [];
      // 重置绘图区域
      dataViewerRef.value?.resetSvg();
      // 清空已选参数和任务
      parameterSelector.value?.clearSelectedTask();
      isLoading.value = false;
      messageRef.value?.show({
        type: "warning",
        content: res?.message || "参数获取失败",
        duration: 3000,
      });
    }
  } catch (error: any) {
    console.error("Failed to fetch parameters:", error);
    parameters.value = [];
    // 重置绘图区域
    dataViewerRef.value?.resetSvg();
    // 清空已选参数和任务
    parameterSelector.value?.clearSelectedTask();
    isLoading.value = false;
    messageRef.value?.show({
      type: "error",
      content: error.response?.data?.msg || error.message || "参数获取失败",
      duration: 3000,
    });
  }

  // 查询故障
  try {
    let params = {
      unitCode: currentUnitCode,
    };
    if (parameterSelector.value?.startDateTime) {
      params.startTime = parameterSelector.value?.startDateTime;
    } else {
      return
    }
    if (parameterSelector.value?.endDateTime) {
      params.endTime = parameterSelector.value?.endDateTime;
    } else {
      return
    }
    const res = await EquipmentAPI.getFaultListByEquipment(params);
    if (res && res.code === 200) {
      faultList.value = res.result || res.data || [];
    } else {
      faultList.value = [];
      console.warn("查询故障返回异常，code:", res?.code);
      messageRef.value?.show({
        type: "warning",
        content: res?.message || "故障获取失败",
        duration: 3000,
      });
    }
  } catch (error: any) {
    faultList.value = [];
    console.error("Failed to fetch fault:", error);
    messageRef.value?.show({
      type: "error",
      content: error.response?.data?.msg || error.message || "故障获取失败",
      duration: 3000,
    });
  }
};
const handleRefreshDataViewer = async () => {
  // 查询故障
  try {
    let params = {
      unitCode: parameterSelector.value?.selectedUnit || localStorage.getItem("unitCode"),
      startTime: parameterSelector.value?.startDateTime,
      endTime: parameterSelector.value?.endDateTime
    };
    const res = await EquipmentAPI.getFaultListByEquipment(params);
    if (res && res.code === 200) {
      faultList.value = res.result || res.data || [];
    } else {
      faultList.value = [];
      console.warn("查询故障返回异常，code:", res?.code);
      messageRef.value?.show({
        type: "warning",
        content: res?.message || "故障获取失败",
        duration: 3000,
      });
    }
  } catch (error: any) {
    faultList.value = [];
    console.error("Failed to fetch fault:", error);
    messageRef.value?.show({
      type: "error",
      content: error.response?.data?.msg || error.message || "故障获取失败",
      duration: 3000,
    });
  }
  // 重新查询绘图数据
  dataViewerRef.value?.refreshDataViewer();
};

// 故障模式切换处理函数
const handleToggleFaultMode = (isActive: boolean) => {
  isFaultModeActive.value = isActive;
  if (dataViewerRef.value) {
    dataViewerRef.value.changeFaultMode(isActive);
  }
};

// 处理故障选择
const handleFaultSelected = (faultId: string[]) => {
  faultIds.value = faultId;
  // 这里可以通知 DataViewer 组件绘制红色竖线
  if (dataViewerRef.value) {
    dataViewerRef.value.updateFaultDisplayMode(
      "",
      faultIds.value,
      faultList.value
    );
  }
};

// 处理故障显示模式变化
const handleFaultDisplayModeChanged = (mode: string) => {
  // 通知DataViewer更新故障显示模式
  if (dataViewerRef.value) {
    dataViewerRef.value.updateFaultDisplayMode(
      mode,
      faultIds.value,
      faultList.value
    );
  }
};

// 打开数据导出
const handleOpenExportData = () => {
  showExportModal.value = true;
};

// 打开相似性检索
const handleOpenSimilaritySearch = () => {
  showSimilaritySearchModal.value = true;
};

// 打开新增样本弹窗
const openAddSample = () => {
  editSampleData.value = null; // 清空编辑样本数据，确保是新增模式
  showSimilaritySearchModal.value = false;
  showAddSampleDialog.value = true;
  // 切换dataViewer测量模式
  if (dataViewerRef.value) {
    dataViewerRef.value.switchToMeasureMode();
  }
};

// 关闭新增样本弹窗
const closeAddSampleDialog = () => {
  showAddSampleDialog.value = false;
  editSampleData.value = null; // 清空编辑样本数据
  showSimilaritySearchModal.value = true;
};

// 保存新增样本
const handleSaveSample = (newSample: any, res: any) => {
  showAddSampleDialog.value = false;
  showSimilaritySearchModal.value = true;
  if (res.code === 200) {
    messageRef.value?.show({
      type: "success",
      content: "样本保存成功",
      duration: 3000,
    });
  } else {
    messageRef.value?.show({
      type: "warning",
      content: "样本保存失败",
      duration: 3000,
    });
  }
};

// 新增样本弹窗更新游标回调
const handleUpdateCursors = (
  updatedCursors: Record<string, Record<string, number>>
) => {
  if (dataViewerRef.value) {
    dataViewerRef.value.updateCursors(updatedCursors);
  }
};

// 处理相似性检索模态框的编辑样本事件
const handleEditSample = (sample: any) => {
  editSampleData.value = sample; // 设置编辑样本数据
  showSimilaritySearchModal.value = false; // 关闭相似性检索弹窗
  showAddSampleDialog.value = true; // 打开编辑样本弹窗
};

// 处理相似性检索模态框的播放样本事件
const handlePlaySample = (sample: any) => {
  // 根据sample.channelNumber找到对应文件名
  // const fileName = selectedChannel.value.find((file: any) => file.channelId === sample.channelId)?.fileName
  // 打开新的窗口
  window.open(
    "?sample=true&paramName=" +
      sample.paramName +
      "&fileName=" +
      sample.fileName
  );
};

// 处理相似性检索模态框的批量标注事件
const handleBatchAnnotate = (results: any[]) => {
  // 这里可以通知 DataViewer 组件绘制高亮
  if (dataViewerRef.value) {
    dataViewerRef.value.updateAnnotate(results);
  }
};

// 处理相似性检索模态框的批量清除标注事件
const handleBatchClearAnnotate = (results: any[]) => {
  // 这里可以通知 DataViewer 组件清除高亮
  if (dataViewerRef.value) {
    dataViewerRef.value.clearAnnotationHighlights(results);
  }
};

// 处理相似性检索模态框的标注事件
const handleAnnotate = (result: any) => {
  // 这里可以通知 DataViewer 组件绘制高亮
  if (dataViewerRef.value) {
    dataViewerRef.value.updateAnnotate([result]);
  }
};

// 处理相似性检索模态框的清除标注事件
const handleClearAnnotate = (result: any) => {
  // 这里可以通知 DataViewer 组件清除高亮
  if (dataViewerRef.value) {
    dataViewerRef.value.clearAnnotationHighlights([result]);
  }
};

// 处理相似性检索模态框的取消所有标注事件
const handleClearAllAnnotate = () => {
  // 这里可以通知 DataViewer 组件清除所有高亮
  if (dataViewerRef.value) {
    dataViewerRef.value.clearAllAnnotationHighlights();
  }
};

// 处理DataViewer组件移除参数的事件
const handleParametersRemoved = (removedParams: string[]) => {
  // 从已选参数列表中移除被移除的参数
  selectedParameters.value = selectedParameters.value.filter(
    (paramId) => !removedParams.includes(paramId)
  );
  // 从已选参数信息中移除被移除的参数
  selectedParametersInfo.value = selectedParametersInfo.value.filter(
    (param) => !removedParams.includes(param.name)
  );

  // 直接通过store清除对应参数的标注状态
  const similarityStore = useSimilarityStore();
  const currentSearchResults = similarityStore.searchResults;

  // 清除被移除参数的标注状态
  const updatedResults = currentSearchResults.map((result) => {
    if (removedParams.includes(result.paramName)) {
      return { ...result, isAnnotated: false };
    }
    return result;
  });

  // 更新store中的状态
  similarityStore.updateSearchResult(updatedResults);

  // 如果SimilaritySearchDialog组件已打开，也通知它更新
  if (similaritySearchModalRef.value) {
    similaritySearchModalRef.value.handleParametersRemoved(removedParams);
  }
};

// 处理测量状态更新
const handleIsMeasuringUpdate = (value: boolean) => {
  if (parameterValueDisplayRef.value) {
    parameterValueDisplayRef.value.updateIsMeasuring(value);
  }
};
</script>

<style>
@import "../../src/assets/css/theme.css";
.app {
  height: 100vh;
  display: flex;
  flex-direction: column;
  background: linear-gradient(135deg, #f8fafc 0%, #f1f5f9 100%);
  overflow: hidden;
}

.layout {
  flex: 1;
  min-height: 0;
  position: relative;
}

.layout::before {
  content: "";
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background: linear-gradient(
        90deg,
        rgba(30, 64, 175, 0.03) 1px,
        transparent 1px
      )
      0 0 / 20px 20px,
    linear-gradient(rgba(30, 64, 175, 0.03) 1px, transparent 1px) 0 0 / 20px
      20px;
  pointer-events: none;
  opacity: 0.5;
  z-index: 0;
}

.header {
  background: rgb(26, 16, 111);
  padding: 0 20px;
  color: #fff;
  display: flex;
  align-items: center;
  height: 5vh;
}

.logo {
  font-size: 20px;
  font-weight: bold;
}

.sider {
  background: var(--main-bg-color);
  backdrop-filter: blur(10px);
  border-right: 1px solid rgba(30, 64, 175, 0.1);
  /* order-right: none; */
  height: 95vh;
  padding: 10px;
  position: relative;
  z-index: 1;
  display: flex;
  flex-direction: column;
  overflow: hidden;
  width: 260px;
  flex-shrink: 0;
  /*transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);*/
}

.sider::before {
  content: "";
  position: absolute;
  right: 0;
  top: 0;
  bottom: 0;
  width: 1px;
  background: var(--main-border-color);
}

.sider-collapsed {
  width: 16px;
  padding: 16px 0;
}

.sider-toggle {
  position: absolute;
  right: -12px;
  top: 50%;
  transform: translateY(-50%);
  background: rgba(255, 255, 255, 0.9);
  border: 1px solid rgba(30, 64, 175, 0.2);
  border-radius: 50%;
  width: 24px;
  height: 24px;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  z-index: 10;
  box-shadow: 0 2px 6px rgba(0, 0, 0, 0.1);
  transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
}

.sider-toggle:hover {
  background: rgba(30, 64, 175, 0.1);
  border-color: rgba(30, 64, 175, 0.3);
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
  transform: translateY(-50%) scale(1.05);
}

.sider-toggle:active {
  transform: translateY(-50%) scale(0.95);
}

.content {
  padding: 16px;
  background: var(--main-bg-color);
  min-height: 0;
  height: 95vh;
  position: relative;
  z-index: 1;
  overflow: hidden;
  flex: 1;
  display: flex;
  flex-direction: column;
  /*transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);*/
}

.sider-collapsed + .content {
  width: calc(100% - 40px);
}

.content-layout {
  background: var(--main-bg-color);
  display: flex;
  height: 100%;
  width: 100%;
  gap: 16px;
  overflow: hidden;
}

.main-content {
  flex: 3;
  background: rgba(255, 255, 255);
  /* backdrop-filter: blur(10px); */
  border-radius: 8px;
  /* box-shadow: 0 4px 20px rgba(0, 0, 0, 0.05); */
  min-width: 0;
  overflow: hidden;
  display: flex;
  flex-direction: column;
  position: relative;
  /* border: 1px solid rgba(30, 64, 175, 0.1); */
}

.main-content::before {
  content: "";
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  height: 4px;
}

.side-content {
  flex: 1;
  min-width: 300px;
  max-width: 400px;
  /* background: rgba(255, 255, 255, 0.7); */
  backdrop-filter: blur(10px);
  border-radius: 8px;
  /* box-shadow: 0 4px 20px rgba(0, 0, 0, 0.05); */
  overflow: auto;
  position: relative;
  /* border: 1px solid rgba(30, 64, 175, 0.1); */
}

.side-content::before {
  content: "";
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  height: 4px;
  /* background: linear-gradient(90deg,
    rgba(56, 189, 248, 0.5) 0%,
    rgba(30, 64, 175, 0.8) 50%,
    rgba(56, 189, 248, 0.5) 100%); */
  z-index: 2;
}

/* 按钮样式 */
.btn-primary {
  background: rgba(30, 64, 175, 0.1);
  border: 1px solid rgba(30, 64, 175, 0.3);
  color: #1e3a8a;
  padding: 8px 16px;
  border-radius: 4px;
  cursor: pointer;
  transition: all 0.3s ease;
  box-shadow: 0 2px 5px rgba(0, 0, 0, 0.05);
  position: relative;
  overflow: hidden;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
}

.btn-primary::before {
  content: "";
  position: absolute;
  top: -10px;
  left: -10px;
  width: 0;
  height: 0;
  background: radial-gradient(
    circle,
    rgba(30, 64, 175, 0.2) 0%,
    transparent 70%
  );
  transform: scale(0);
  border-radius: 50%;
  opacity: 0;
  transition: transform 0.5s, opacity 0.5s;
  z-index: -1;
}

.btn-primary:hover::before {
  width: 150%;
  height: 150%;
  transform: scale(3);
  opacity: 1;
}

.btn-primary:hover {
  background: rgb(30, 64, 175);
  border-color: rgba(30, 64, 175, 0.4);
  transform: translateY(-1px);
  box-shadow: 0 4px 10px rgba(0, 0, 0, 0.1), 0 0 0 2px rgba(59, 130, 246, 0.1);
}

/* 模态窗口样式 */
.modal-container {
  position: fixed;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 50;
  background-color: rgba(0, 0, 0, 0.3);
  backdrop-filter: blur(4px);
}

.modal-overlay {
  position: absolute;
  inset: 0;
  cursor: pointer;
}

.import-btn {
  font-size: 15px;
  padding: 8px 10px;
  border-radius: 4px;
  cursor: pointer;
  position: relative;
  overflow: hidden;
  display: flex;
  align-items: center;
  justify-content: center;
}

/* 引导蒙层样式 */
.guide-overlay {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background-color: rgba(0, 0, 0, 0.6);
  display: flex;
  justify-content: center;
  align-items: center;
  z-index: 1100;
  backdrop-filter: blur(3px);
}

.guide-modal {
  backdrop-filter: blur(10px);
  border-radius: 12px;
  width: 90%;
  max-width: 500px;
  overflow: hidden;
  box-shadow: 0 25px 50px -12px rgba(0, 0, 0, 0.15);
  animation: guideModalAppear 0.3s ease-out;
}
.guide-modal::before {
  content: "";
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  height: 4px;
}

@keyframes guideModalAppear {
  from {
    opacity: 0;
    transform: translateY(30px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

.guide-header {
  padding: 16px 20px;
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.guide-title {
  margin: 0;
  font-size: 18px;
  font-weight: 600;
  color: var(--text-color);
}

.guide-close {
  background: none;
  border: none;
  padding: 4px;
  cursor: pointer;
  color: var(--text-color);
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 4px;
}

.guide-close:hover {
  /*background-color: rgba(0, 0, 0, 0.05);*/
  color: var(--btn-click-color);
}

.guide-content {
  padding: 20px;
  text-align: center;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
}

.guide-content p {
  margin-bottom: 20px;
  color: var(--text-color);
  font-size: 16px;
}

/* 1024*768分辨率适配 */
@media (max-width: 1024px) {
  /* 头部样式 */
  .header {
    height: 40px;
    padding: 0 15px;
  }

  .logo {
    font-size: 16px;
  }

  /* 减小侧边栏宽度 */
  .sider {
    width: 180px;
    padding: 10px;
  }

  /* 调整主内容和侧内容之间的间距 */
  .content-layout {
    gap: 6px;
  }

  /* 减小侧内容区域的宽度 */
  .side-content {
    min-width: 220px;
    max-width: 260px;
  }

  /* 调整按钮尺寸 */
  .tech-btn,
  .import-btn {
    padding: 4px 6px;
    font-size: 11px;
  }

  /* 调整按钮中的图标尺寸 */
  .tech-btn svg,
  .import-btn svg {
    width: 12px;
    height: 12px;
    min-width: 12px;
  }

  /* 图标和文字水平间距减小 */
  .import-btn svg {
    margin-right: 3px;
  }

  /* 调整模态窗口尺寸 */
  .modal-content {
    width: 70%;
    max-width: 500px;
  }

  /* 调整页面内边距 */
  .content {
    padding: 10px;
  }

  /* 左侧导入和文件选择按钮排列调整 */
  .sider .flex.w-full {
    /* flex-direction: column; */
    gap: 4px !important;
  }

  /* 导入按钮全宽 */
  .sider .flex.w-full .import-btn {
    width: 100% !important;
  }

  /* 让插件管理按钮更紧凑 */
  .sider .import-btn.w-full {
    margin-bottom: 5px;
  }

  /* 只显示图标的按钮 */
  .sider-toggle {
    width: 20px;
    height: 20px;
    right: -10px;
  }

  .sider-toggle svg {
    width: 10px;
    height: 10px;
  }

  .sider-collapsed {
    width: 16px;
    padding: 16px 0;
  }
}

.loading-overlay {
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background-color: rgb(220, 225, 230, 0.5);
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  z-index: 9999;
}

.spinner {
  border: 8px solid #f3f3f3;
  border-top: 8px solid #3498db;
  border-radius: 50%;
  width: 60px;
  height: 60px;
  animation: spin 1s linear infinite;
}

@keyframes spin {
  0% {
    transform: rotate(0deg);
  }
  100% {
    transform: rotate(360deg);
  }
}
.loading-text {
  color: var(--text-color);
  font-size: 14px;
  font-weight: bold;
  margin-top: 10px;
}
</style>
